import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.events.ProgressEvent;
import flash.net.FileReference;
import flash.net.FileReferenceList;
import flash.events.IEventDispatcher;
import flash.external.ExternalInterface;
import flash.net.URLRequest;

class FileBrowser
{
	private var isMulti:Bool;
	
	private var file:FileReference;
	
	private var list:FileReferenceList;
	
	private var fileList:Array<FileReference>;
	
	public var id:String;
	
	private var prefix:String;
	
	private var uploadHelper:UploadHelper;
	
	public function new(multi:Bool)
	{
		FileBrowser(multi);
	}
	
	public function FileBrowser(multi:Bool)
	{
		isMulti = multi;
		prefix = "Pipe.Event";
		
		fileList = new Array();
		
		list = new FileReferenceList();
    	list.addEventListener(Event.CANCEL, eventCancel);
		list.addEventListener(Event.SELECT, eventMultiSelect);
		list.addEventListener(Event.OPEN, eventOpen);
        list.addEventListener(ProgressEvent.PROGRESS, eventProgress);
		list.addEventListener(Event.COMPLETE, eventComplete);
		list.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		list.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);		
	}
	
	public function getFileList()
	{
		return fileList;
	}
	
	public function setListeners(ref:FileReference)
	{
    	ref.addEventListener(Event.CANCEL, eventCancel);
		ref.addEventListener(Event.SELECT, eventSingleSelect);
		ref.addEventListener(Event.OPEN, eventOpen);
        ref.addEventListener(ProgressEvent.PROGRESS, eventProgress);
		ref.addEventListener(Event.COMPLETE, eventComplete);
		ref.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		ref.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
		return file;
	}
	
	public function browse()
	{
		if(isMulti) {
			return list.browse();
		} else {
			file = new FileReference();
			setListeners(file);
			return file.browse();
		}
	}
	
	public function eventCancel(event:Event)
	{
		ExternalInterface.call(prefix+".cancel", id);
	}
	
	public function eventSingleSelect(event:Event)
	{
		handleSelect(event.target);
		// @todo: usunac to w chuj
		//upload(new Array());
	}
	
	private function eventMultiSelect(event:Event)
	{
		var i:Int;
		for(i in 0 ... event.target.fileList.length) {
			var f:FileReference = event.target.fileList[i];
			setListeners(f);
			handleSelect(f);
		}
		
		// @todo: usunac to w chuj
		//upload(new Array());

	}
	
	private function handleSelect(ref:FileReference)
	{
		var fId:Int = fileList.length;
		fileList.push(ref);
		ExternalInterface.call(prefix+".select", id, fId, ref.name, ref.size);
	}
	
	public function remove(index:Int)
	{
		fileList[index] = null;
		for(i in 0 ... fileList.length) {
			trace(fileList[i]);
		}
		
		return true;
	}
	
	public function eventOpen(event:Event)
	{
		//trace("Open: "+event.target.name); 
	}
	
	public function eventProgress(event:ProgressEvent)
	{
		trace("Progress: "+(uploadHelper.bytesLoaded+event.bytesLoaded)+"/"+uploadHelper.bytesTotal);
	}
	
	public function eventComplete(event:Event)
	{
		uploadHelper.progress = 0;
		uploadHelper.bytesLoaded += event.target.size;
		uploadHelper.filesLoaded++;
		
		trace("Progress: "+uploadHelper.bytesLoaded+"/"+uploadHelper.bytesTotal);
		
		if(uploadHelper.hasMoreFiles()) {
			fileList[uploadHelper.getFileId()].upload(new URLRequest("http://wpjobboard.net/haxe/upload.php"));
		}
	}
	
	public function upload(idArr:Array<Int>)
	{
		var i:Int;
		if(idArr.length == 0) {
			idArr = new Array();
			for(i in 0 ... fileList.length) {
				if(Std.is(fileList[i], FileReference)) {
					idArr.push(i);
				}
			}
		}
		
		uploadHelper = new UploadHelper();
		
		for(i in 0 ... idArr.length) {
			if(Std.is(fileList[idArr[i]], FileReference)) {
				uploadHelper.bytesTotal += fileList[idArr[i]].size;
				uploadHelper.filesTotal++;
			}
		}
		
		uploadHelper.idList = idArr;
		fileList[idArr[0]].upload(new URLRequest("http://wpjobboard.net/haxe/upload.php"));
		
	}
	
	private function ioErrorHandler(event:IOErrorEvent) 
	{
            trace("ioErrorHandler: " + event);
    }

    private function securityErrorHandler(event:SecurityErrorEvent) 
	{
        trace("securityErrorHandler: " + event);
    }

	
}
